/*
 * Copyright (c) 2008-2021 浩瀚深度 All Rights Reserved.
 *
 * <p>FileName: SyslogMonitorServiceImpl.java</p>
 *
 * @author zz
 * @date 2024/3/11
 * @version 1.0
 * History:
 * v1.0.0 2024/3/11 Create
 */
package com.monitor.service.impl;

import com.monitor.entity.SyslogMonitor;
import com.monitor.mapper.SyslogMapper;
import com.monitor.service.SyslogMonitorService;
import lombok.extern.slf4j.Slf4j;
import org.graylog2.syslog4j.SyslogIF;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>Title: SyslogMonitorServiceImpl</p>
 * <p>Description: </p>
 *
 * @author zz
 */
@Slf4j
@Service
public class SyslogMonitorServiceImpl implements SyslogMonitorService {
    @Autowired
    private SyslogMapper syslogMapper;

    private static final ConcurrentHashMap<String, SyslogIF> syslogInstances = new ConcurrentHashMap<>();

    @Override
    public void sendMsg(SyslogMonitor msg) {
        try {
            String ip = (msg.getSyslogIp() == null) ? "127.0.0.1" : msg.getSyslogIp();
            int port = (msg.getSyslogPort() == null) ? 514 : msg.getSyslogPort();

            String syslogMessage = "";
            Integer op = msg.getOp();
            Integer type = msg.getType();
            Integer sysLogId = msg.getSyslogId();
            String content = URLDecoder.decode(msg.getContent(), "iso8859-1");
            String objId = extractObjId(content);
            // 构建消息格式（Kuanguang: <content>, Op=<op>, ObjId=<objId>, SysLogId=<sysLogId>, Type=<type>）
            syslogMessage = String.format("Kuanguang: %s, Op=%d, ObjId=%s, SysLogId=%d, Type=%d",
                    content, op, objId, sysLogId, type);
            sendSyslogMessage(syslogMessage, "Kuanguang", 129, ip, port);

        } catch (Exception e) {
            log.error("发送失败:" + e);
        }
    }

    @Override
    public void sendSelfDefineMsg(SyslogMonitor msg) {
        try {
            String ip = (msg.getSyslogIp() == null) ? "127.0.0.1" : msg.getSyslogIp();
            int port = (msg.getSyslogPort() == null) ? 514 : msg.getSyslogPort();
            String syslogMessage = msg.getContent();
            try (DatagramSocket datagramSocket = new DatagramSocket()) {
                InetSocketAddress address = new InetSocketAddress(ip, port);
                datagramSocket.connect(address);

                byte[] bytes = syslogMessage.getBytes(StandardCharsets.UTF_8);
                DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
                datagramSocket.send(packet);
                log.info("告警日志：{}发送成功", syslogMessage);
            } catch (Exception e) {
                log.error("告警日志：{}发送失败", syslogMessage, e);
            }
        } catch (Exception e) {
            log.error("发送失败:" + e);
        }
    }

    public static void sendSyslogMessage(String message, String hostname, int priority, String ip, int port) {
        try {
            // 构造时间戳
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd HH:mm:ss");
            String timestamp = LocalDateTime.now().format(formatter);

            // 构造Syslog消息
            String syslogMessage = String.format("<%d>%s %s", priority, timestamp, message);

            // 转换为字节
            byte[] messageBytes = syslogMessage.getBytes(StandardCharsets.UTF_8);

            // 发送消息
            try (DatagramSocket socket = new DatagramSocket()) {
                InetAddress address = InetAddress.getByName(ip);
                DatagramPacket packet = new DatagramPacket(messageBytes, messageBytes.length, address, port);
                socket.send(packet);
                log.info("Syslog消息发送成功: " + syslogMessage);
            }
        } catch (Exception e) {
            log.error("Syslog消息发送失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // 示例参数
        String srcIp = "10.10.20.25";
        String dstIp = "10.10.4.178";
        int dstPort = 514;
        String data = "<129>Mar 20 14:32:20 Kuanguang: Slot 1 iEng Core Temperature Threshold alarm,Op=16, ObjId=1, SysLogId=21, Type=1";

        // 调用私有方法执行Python脚本
        callPythonScript(srcIp, dstIp, dstPort, data);
    }

    private static void callPythonScript(String srcIp, String dstIp, int dstPort, String data) {
        // 或者是具体路径，比如 "/usr/bin/python"
        String pythonInterpreterPath = "python";
        //脚本路径
        String pythonScriptPath = "send_packet.py";

        try {
            // 使用ProcessBuilder调用Python脚本
            ProcessBuilder builder = new ProcessBuilder(
                    pythonInterpreterPath,
                    pythonScriptPath,
                    srcIp,
                    dstIp,
                    String.valueOf(dstPort),
                    data
            );
            Process process = builder.start();

            // 读取脚本的标准输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            // 等待进程结束
            int exitCode = process.waitFor();
            System.out.println("Exited with code : " + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    private String extractObjId(String content) {
        // 忽略大小写，将content拆分为单词数组
        String[] parts = content.split("\\s+");
        for (int i = 0; i < parts.length; i++) {
            // 检查当前单词是否忽略大小写等于"Intf"或者"Slot"
            if (parts[i].equalsIgnoreCase("Intf") || parts[i].equalsIgnoreCase("Slot")) {
                if (i + 1 < parts.length) {
                    // 返回紧接着"Intf"或"Slot"的单词
                    return parts[i + 1];
                }
            }
        }
        // 如果不存在"Intf"或者"Slot"，则返回空字符串
        return "";
    }


    @Override
    public void create(com.monitor.entity.Syslog msg) {
        syslogMapper.insert(msg);
    }

    @Override
    public void deleteSyslog(com.monitor.entity.Syslog msg) {
        syslogMapper.deleteById(msg.getId());
    }
}
